package servlet;

import ejb.sessionBeans.AvisoFacadeRemote;
import estadisticas.AvisosMesEst;
import estadisticas.TiempoAtencionEst;
import estadisticas.TiposAvisoEst;
import estadisticas.TiposSolucionEst;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;

/**
 * Clase Estadisticas Genera y envía las estadísticas generadas a partir de los
 * datos obtenidos de la Base de Datos.
 *
 * @author Jesús Barriga
 * @version 1.0, Enero-2012
 */
@WebServlet(name = "Estadisticas", urlPatterns = {"/Estadisticas"})
public class Estadisticas extends HttpServlet {

    @EJB
    private AvisoFacadeRemote avisoFacade;

    /**
     * Processes requests for both HTTP
     * <code>GET</code> and
     * <code>POST</code> methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("image/png");
        OutputStream out = response.getOutputStream();

        try {
            String tipo = request.getParameter("tipo");
            JFreeChart chart = null;
            if (tipo.equals("1")) {
                chart = estAvisosMes();
            } else if (tipo.equals("2")) {
                chart = estTiempoAtencion();
            } else if (tipo.equals("3")) {
                chart = estTiposAviso();
            } else if (tipo.equals("4")) {
                chart = estTiposSolucion();
            }
            if (chart != null) {
                ChartUtilities.writeChartAsPNG(out, chart, 700, 500);
            }
        } catch (Exception e) {
            System.err.println(e.toString());
        } finally {
            out.close();
        }
    }

    /**
     * Genera estadistica de los tipos de aviso recibidos.
     *
     * @return Gráfico de tarta correspondiente
     */
    private JFreeChart estTiposAviso() {
        List<TiposAvisoEst> lista = (List<TiposAvisoEst>) avisoFacade.getTiposAviso();
        DefaultPieDataset data = new DefaultPieDataset();
        long total = 0;

        for (TiposAvisoEst a : lista) {
            total = total + a.getNumAvisos();
        }
        for (TiposAvisoEst a : lista) {
            float avisos = ((float) a.getNumAvisos() / (float) total) * 100;
            data.setValue(a.getTipoAviso(), avisos);
        }

        JFreeChart chart = ChartFactory.createPieChart(
                "Porcentaje de Avisos por categorías", data, true, true, false);
        return chart;
    }

    /**
     * Genera estadistica de tipos de solución empleadas.
     *
     * @return Gráfico de tarta correspondiente
     */
    private JFreeChart estTiposSolucion() {

        List<TiposSolucionEst> lista = (List<TiposSolucionEst>) avisoFacade.getTiposSolucion();
        DefaultPieDataset data = new DefaultPieDataset();
        long total = 0;

        for (TiposSolucionEst a : lista) {
            total = total + a.getNumAvisos();
        }
        for (TiposSolucionEst a : lista) {
            float avisos = ((float) a.getNumAvisos() / (float) total) * 100;
            data.setValue(a.getTipoSolucion(), avisos);
        }

        JFreeChart chart = ChartFactory.createPieChart(
                "Porcentaje de Avisos por tipo de solución", data, true, true, false);
        return chart;
    }

    /**
     * Genera estadistica de avisos por mes.
     *
     * @return Gráfico de barras correspondiente.
     */
    private JFreeChart estAvisosMes() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        List<AvisosMesEst> lista = (List<AvisosMesEst>) avisoFacade.getAvisosMes();

        if (!lista.isEmpty()) {
            for (AvisosMesEst a : lista) {
                dataset.addValue(a.getNumAvisos(), "Avisos", this.traduceMes(a.getMes()));
            }
        }

        JFreeChart chart = ChartFactory.createBarChart3D(
                "Avisos por mes",
                "Meses",
                "Nº de Avisos",
                dataset,
                PlotOrientation.VERTICAL,
                true,
                true,
                false);
        return chart;
    }

    /**
     * Genera estadistica de avisos por mes.
     *
     * @return Gráfico de barras correspondiente.
     */
    private JFreeChart estTiempoAtencion() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        List<TiempoAtencionEst> lista = (List<TiempoAtencionEst>) avisoFacade.getTiempoAtencion();
        int tiempos[] = new int[6];

        for (TiempoAtencionEst a : lista) {
            if (a.getTiemposDeAtencion() < 5) {
                ++tiempos[0];
            } else if (a.getTiemposDeAtencion() < 10) {
                ++tiempos[1];
            } else if (a.getTiemposDeAtencion() < 15) {
                ++tiempos[2];
            } else if (a.getTiemposDeAtencion() < 30) {
                ++tiempos[3];
            } else if (a.getTiemposDeAtencion() < 60) {
                ++tiempos[4];
            } else {
                ++tiempos[5];
            }
        }

        dataset.addValue(tiempos[0], "Tiempo", "0 a 5");
        dataset.addValue(tiempos[1], "Tiempo", "5 a 10");
        dataset.addValue(tiempos[2], "Tiempo", "10 a 15");
        dataset.addValue(tiempos[3], "Tiempo", "15 a 30");
        dataset.addValue(tiempos[4], "Tiempo", "30 a 60");
        dataset.addValue(tiempos[5], "Tiempo", "> 60");

        JFreeChart chart = ChartFactory.createBarChart3D(
                "Tiempos de respuesta",
                "Tiempos",
                "Avisos",
                dataset,
                PlotOrientation.VERTICAL,
                true,
                true,
                false);
        return chart;
    }

    /**
     * Realiza la traducción dentre meses numéricos y sus nombres para la
     * gráfica.
     *
     * @return Cadena correspondiente al mes introducido.
     */
    private String traduceMes(int numMes) {
        switch (numMes) {
            case 1:
                return "Enero";
            case 2:
                return "Febrero";
            case 3:
                return "Marzo";
            case 4:
                return "Abril";
            case 5:
                return "Mayo";
            case 6:
                return "Junio";
            case 7:
                return "Julio";
            case 8:
                return "Agosto";
            case 9:
                return "Septiembre";
            case 10:
                return "Octubre";
            case 11:
                return "Noviembre";
            case 12:
                return "Diciembre";
            default:
                return "";
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP
     * <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP
     * <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
